home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
program
/
misc
/
fpl-v13.lha
/
fpl
/
src
/
reference.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-28
|
9KB
|
281 lines
/******************************************************************************
* FREXX PROGRAMMING LANGUAGE *
******************************************************************************
Reference.c
Routines for interpreting variable references from the interface function.
*****************************************************************************/
/************************************************************************
* *
* fpl.library - A shared library interpreting script langauge. *
* Copyright (C) 1992-1994 FrexxWare *
* Author: Daniel Stenberg *
* *
* This program is free software; you may redistribute for non *
* commercial purposes only. Commercial programs must have a written *
* permission from the author to use FPL. FPL is *NOT* public domain! *
* Any provided source code is only for reference and for assurance *
* that users should be able to compile FPL on any operating system *
* he/she wants to use it in! *
* *
* You may not change, resource, patch files or in any way reverse *
* engineer anything in the FPL package. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* Daniel Stenberg *
* Ankdammsgatan 36, 4tr *
* S-171 43 Solna *
* Sweden *
* *
* FidoNet 2:201/328 email:dast@sth.frontec.se *
* *
************************************************************************/
#include <stddef.h>
#include "script.h"
#if defined(UNIX)
#include <stdio.h>
#endif
#include "reference.h"
struct fplStr EmptyString={0,0,0};
#ifndef AMIGA /* if not using SAS/C on Amiga */
#ifdef VARARG_FUNCTIONS
/*
* The following stub functions to the actual library functions was done
* to make this run under SunOS 4.1.x using gcc. Thanks to Bernd Noll
* (b_noll@sun.rhrk.un) for this contribution!
*/
long fplReferenceTags(void *anchor, void *refID, ...)
{
va_list tags;
long ret;
va_start(tags, format); /* get parameter list */
ret = fplReference(anchor, refID, (unsigned long *)tags);
va_end(tags)
return ret;
}
#else /* VARARG_FUNCTIONS */
long fplReferenceTags(void *anchor, void *refID, unsigned long tags, ...)
{
return(fplReference(anchor, refID, &tags));
}
#endif
#endif
/**********************************************************************
*
* fplReference()
*
* Handles all referencing to FPL internal symbols from the interface
* function.
*
******/
ReturnCode PREFIX
fplReference(AREG(0) struct Data *scr,
AREG(1) struct Identifier *ident,
AREG(2) unsigned long *tags)
{
ReturnCode ret = FPL_OK;
long item=0;
long a=0;
long *dims;
long my_strlen=-1;
struct fplRef *ref;
while(tags && *tags) {
switch(*tags++) {
case FPLREF_ARRAY_RESIZE: /* version 11 magic! */
if(ident->flags&FPL_VARIABLE && ident->data.variable.num) {
/*
* It is a variable and it is at least a one dimensional array!
*/
ref = (struct fplRef *)(*tags);
CALL( ArrayResize(scr,
ref->Dimensions,
ref->ArraySize,
ident));
}
break;
case FPLREF_ARRAY_ITEM:
if(ident->flags&FPL_VARIABLE) {
dims = (long *)(*tags);
while(dims[a]>0)
a++;
item = ArrayNum(a, ident->data.variable.num,
dims, ident->data.variable.dims);
if(item<0)
item=0; /* just ignore stupid values! */
a=0; /* reset 'a' again */
}
break;
case FPLREF_ARRAY_INFO:
/*
* Fill out the structure given to us by the caller!
*/
if(ident->flags&FPL_VARIABLE && ident->data.variable.num) {
ref = (struct fplRef *)(*tags);
ref->Dimensions = ident->data.variable.num; /* number of dims */
ref->ArraySize = ident->data.variable.dims; /* actual dims */
}
break;
case FPLREF_NAME:
/*
* Receive name in supplied char pointer!
*/
*(uchar **)(*tags) = ident->name;
break;
case FPLREF_TYPE:
/*
* Receive flags in supplied long!
*/
*(long *)(*tags) =
(ident->flags&FPL_STRING_VARIABLE?FPLREF_TYPE_STRING:0)|
(ident->flags&FPL_INT_VARIABLE?FPLREF_TYPE_INTEGER:0)|
(ident->flags&FPL_VARIABLE?
(ident->data.variable.num?FPLREF_TYPE_ARRAY:0):0 )|
(ident->flags&FPL_FUNCTION?FPLREF_TYPE_FUNCTION:0);
break;
case FPLREF_GET_STRING:
if(ident->flags&FPL_STRING_VARIABLE &&
item<ident->data.variable.size) {
if(ident->data.variable.var.str[item]) {
/*
* This is a string!
*/
*(uchar **)(*tags) = ident->data.variable.var.str[item]->string;
}
else {
/*
* Can't return NULL for no string, return pointer to ""!
*/
*(uchar **)(*tags) = EmptyString.string;
}
}
else {
*(uchar **)(*tags) = NULL;
}
break;
case FPLREF_SET_MY_STRLEN:
my_strlen=(long)(*tags);
break;
case FPLREF_SET_MY_STRING:
a=1;
case FPLREF_SET_STRING:
if(ident->flags&FPL_STRING_VARIABLE &&
item<ident->data.variable.size &&
*tags) {
/*
* Get the allocation type.
*/
uchar type=MALLOC_DYNAMIC; /* default memory state */
struct fplStr *str;
if(ident->data.variable.var.str[item]) {
type = TypeMem(ident->data.variable.var.str[item]);
if(MALLOC_STATIC == type ) {
/*
* The previous allocation was static!
*/
FREEA( ident->data.variable.var.str[item] );
}
else {
FREE( ident->data.variable.var.str[item] );
}
}
if(1 == a) {
/*
* This is a FPLREF_SET_MY_STRING call. That means we got a regular
* C style char pointer to a zero terminated string here, allocate
* a regular FPL string and copy the string into that one
*/
register long len = 0>my_strlen?strlen((uchar *)*tags):my_strlen;
GETMEM(str, len + sizeof(struct fplStr));
str->alloc= len;
str->len= len; /* set default to entire string */
/* copy the data into the string */
memcpy(str->string, (uchar *)(*tags), len);
}
else {
/*
* We received a pointer to the ->string member of a fplStr struct.
* Make 'str' point to the struct itself!
*/
str = (struct fplStr *)
(((uchar *)(*tags)) - offsetof(struct fplStr, string));
}
ident->data.variable.var.str[item] = str;
str->string[str->len] = '\0'; /* force zero termination! */
if(MALLOC_STATIC == type || ident->flags&FPL_EXPORT_SYMBOL) {
/*
* The previous memory was static, which probably means that
* this is an exported or global variable which required
* static existance. Swap it back to that state!
*/
SwapMem(scr,
ident->data.variable.var.str[item],
MALLOC_STATIC);
}
else {
/*
* Make sure this allocation is dynamic!
*/
SwapMem(scr,
ident->data.variable.var.str[item],
MALLOC_DYNAMIC);
}
}
else {
*(uchar **)(*tags) = NULL;
}
break;
case FPLREF_GET_INTEGER:
if(ident->flags&FPL_INT_VARIABLE &&
item<ident->data.variable.size) {
/* we supply a pointer to it, then we can return NULL if there was
something that looked fishy! */
*(long **)(*tags) = &ident->data.variable.var.val32[item];
}
else {
*(long **)(*tags) = NULL;
}
break;
case FPLREF_SET_INTEGER:
if(ident->flags&FPL_INT_VARIABLE &&
item<ident->data.variable.size) {
/* set integer variable item */
ident->data.variable.var.val32[item] = (*tags);
}
break;
}
tags++;
}
return ret;
}